Cross Compile Rust For OpenWRT

您所在的位置:网站首页 mips mipsel 区别 Cross Compile Rust For OpenWRT

Cross Compile Rust For OpenWRT

2023-11-16 13:16| 来源: 网络整理| 查看: 265

1. 背景

编译环境(x86_64,Windows Subsystem for Linux):

OpenWRT SDK: OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2

工具链目录:/mnt/f/wsl/OpenWRT/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2

rust 版本:1.46.0(官方不会构建 uclibc 的版本,所以有些版本下,uclibc 会编译失败,例如 1.48.0。1.43.0、1.46.0 是可以编译通过的)

目录内的 “mips-openwrt-linux-“ 工具是指向 “mips-openwrt-linux-uclibc-“ 的软连接,即工具链使用的是 uclibc 的版本。

uClibc 和 glibc 有差异,有些应用使用 uClibc 可能无法编译。

Rust 目前的官方构建还不支持 mips-unknown-linux-uclibc[1],从目前 Rust 支持的平台来看,uclibc 对应的 std 是支持的(但是稳定版中没有),target-list 中虽然可以显示出 mips-unknown-linux-uclibc,但是添加是会显示失败。

$ rustc --print target-list | grep mips mips-unknown-linux-gnu mips-unknown-linux-musl mips-unknown-linux-uclibc 2. 设置环境变量

需要将工具链相关的路径添加到环境变量中[2]:

1 2 3 export PATH=$PATH:/mnt/f/wsl/OpenWRT/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/ export STAGING_DIR=/mnt/f/wsl/OpenWRT/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2 export CC_mips_unknown_linux_uclibc=mips-openwrt-linux-uclibc-gcc 3. 交叉编译

基于 tag 1.46.0 创建分支 1.46.0

1 git checkout -b 1.46.0 1.46.0 --recurse-submodules -f

从 config.toml.example 复制一份 config.toml 文件,修改 config.toml 文件,指定要编译的 target,使能工具编译(默认不编),指定安装目录(相对路径,如果是系统的路径,安装时没有权限,会失败)及交叉编译用到的工具链:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 修改 target = ["mips-unknown-linux-uclibc"] extended = true tools = ["cargo", "rls", "clippy", "rustfmt", "analysis", "src"] prefix = "/mnt/f/wsl/usr/local" sysconfdir = "etc" docdir = "share/doc/rust" bindir = "bin" libdir = "lib" mandir = "share/man" # 添加(在 [target.x86_64-unknown-linux-gnu] 之后) [target.mips-unknown-linux-uclibc] cc = "mips-openwrt-linux-uclibc-gcc" cxx = "mips-openwrt-linux-uclibc-c++" ar = "mips-openwrt-linux-uclibc-ar" linker = "mips-openwrt-linux-uclibc-gcc"

编译并安装:

1 ~/wsl/rust$ ./x.py build && ./x.py install

安装完成后库和可执行文件位于以下目录:

~/wsl/usr/local/lib~/wsl/usr/local/bin

如果安装了 rustup,可以为其添加刚才编译好的工具链[3]:

1 $ rustup toolchain link my_toolchain ~/wsl/usr/local

效果是在 .rustup 目录下创建软链接。

添加之后可以看到对应的工具链:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 $ rustup show Default host: x86_64-unknown-linux-gnu rustup home: /home/dell/.rustup installed toolchains -------------------- stable-x86_64-unknown-linux-gnu (default) my_toolchain active toolchain ---------------- stable-x86_64-unknown-linux-gnu (default) rustc 1.48.0 (7eac88abb 2020-11-16) # 将编译好的工具链设置为默认工具链 $ rustup default my_toolchain info: default toolchain set to 'my_toolchain' $ rustup show Default host: x86_64-unknown-linux-gnu rustup home: /home/dell/.rustup installed toolchains -------------------- stable-x86_64-unknown-linux-gnu my_toolchain (default) active toolchain ---------------- my_toolchain (default) rustc 1.46.0-dev

如果编译时没有重新编译 cargo,而是使用预先安装好的,可能会存在和 rustc 版本不匹配的问题(cargo 传给 rustc 的某些选项,rustc 无法识别)。例如,cargo 版本号为 1.5,rustc 版本号为 1.43.0,cargo 传给 rustc 的选项 embed-bitcode 无法被 rustc 识别。编译时顺带编译了 cargo,添加 rustup 工具链并且将添加的编译链设置为默认工具链后,调用的 cargo 就是顺带编译出的 cargo,不存在版本不匹配的问题。

如果没有安装 rustup,将路径添加到环境变量(或者修改 ~/.profile 文件)即可:

1 2 $ export PATH=$PATH:~/wsl/usr/local/bin $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/wsl/usr/local/lib 4. 测试

编译 hello 工程:

1 $ cargo new hello

添加 hello/.cargo/config.toml 配置文件:

1 2 3 [target.mips-unknown-linux-uclibc] linker = "mips-openwrt-linux-uclibc-gcc" ar = "mips-openwrt-linux-uclibc-ar"

构建:

1 2 hello$ cargo build --target=mips-unknown-linux-uclibc hello$ mips-openwrt-linux-strip target/mips-unknown-linux-uclibc/debug/hello

或者在 config.toml 中增加 build 选项:

1 2 3 4 5 6 7 [build] target = "mips-unknown-linux-uclibc" # target = "x86_64-unknown-linux-gnu" [target.mips-unknown-linux-uclibc] linker = "mips-openwrt-linux-uclibc-gcc" ar = "mips-openwrt-linux-uclibc-ar"

构建:

1 hello$ cargo build

如果编译单个文件:

1 2 $ rustc hello.rs --target=mips-unknown-linux-uclibc -C linker=mips-openwrt-linux-uclibc-gcc -C ar=mips-openwrt-uclibc-ar $ mips-openwrt-linux-strip hello 参考

[1] https://forge.rust-lang.org/release/platform-support.html

[2] https://openwrt.org/docs/guide-developer/crosscompile

[3] https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#creating-a-rustup-toolchain



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3